package com.xiaogao.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaogao.autofill.annotation.FillUserInfo;
import com.xiaogao.common.exception.BusinessException;
import com.xiaogao.common.utils.BeanListUtils;
import com.xiaogao.common.utils.token.JwtUtils;
import com.xiaogao.sys.mapper.SysPermMapper;
import com.xiaogao.sys.model.SysPerm;
import com.xiaogao.sys.model.SysRolePerm;
import com.xiaogao.sys.model.SysUser;
import com.xiaogao.sys.model.SysUserRole;
import com.xiaogao.sys.request.perm.AddParam;
import com.xiaogao.sys.request.perm.UpdateParam;
import com.xiaogao.sys.response.SysPermResponse;
import com.xiaogao.sys.service.SysPermService;
import com.xiaogao.sys.service.SysRolePermService;
import com.xiaogao.sys.service.SysUserRoleService;
import com.xiaogao.sys.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class SysPermServiceImpl extends ServiceImpl<SysPermMapper, SysPerm>  implements SysPermService {
    @Autowired
    private SysPermMapper sysPermMapper;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRolePermService sysRolePermService;

    @Override
    public List<SysPermResponse> queryByUserId(String userId) {
        // 如果是系统管理员
        SysUser sysUser = sysUserService.getById(userId);
        if (JwtUtils.isAdmin(sysUser.getUsername())) {
            LambdaQueryWrapper<SysPerm> wrapper = new LambdaQueryWrapper<>();
            wrapper.orderByAsc(SysPerm::getSort);
            List<SysPerm> sysPermList = sysPermMapper.selectList(wrapper);
            return BeanListUtils.copyList(sysPermList, SysPermResponse.class);
        } else {
            // 1、根据userId查roleIds
            LambdaQueryWrapper<SysUserRole> sysUserRoleWrapper = new LambdaQueryWrapper<>();
            sysUserRoleWrapper.eq(SysUserRole::getUserId, userId);
            sysUserRoleWrapper.select(SysUserRole::getRoleId);
            List<String> roleIds = sysUserRoleService.listObjs(sysUserRoleWrapper);
            if (roleIds.isEmpty()) {
                return new ArrayList<>();
            }
            // 2、根据roleIds查permIds
            LambdaQueryWrapper<SysRolePerm> sysRolePermWrapper = new LambdaQueryWrapper<>();
            sysRolePermWrapper.in(SysRolePerm::getRoleId, roleIds);
            sysRolePermWrapper.select(SysRolePerm::getPermId);
            List<String> permIds = sysRolePermService.listObjs(sysRolePermWrapper);
            if (permIds.isEmpty()) {
                return new ArrayList<>();
            }
            // 3、通过permIds递归查询所有的父级permIds
            List<String> allPermIds = sysPermMapper.queryParentAndSelfPermIds(permIds);

            // 4、根据permIds查sysPermList
            List<SysPerm> sysPermList = sysPermMapper.selectByIds(allPermIds);
            return BeanListUtils.copyList(sysPermList, SysPermResponse.class);
        }
    }

    @FillUserInfo
    @Override
    public List<SysPermResponse> querySelect() {
        LambdaQueryWrapper<SysPerm> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(SysPerm::getSort);
        List<SysPerm> sysPermList = sysPermMapper.selectList(wrapper);
        return BeanListUtils.copyList(sysPermList, SysPermResponse.class);
    }

    @Override
    public void add(AddParam addParam) {
        SysPerm sysPerm = new SysPerm();
        BeanUtils.copyProperties(addParam, sysPerm);
        sysPermMapper.insert(sysPerm);
    }


    @Override
    public void update(UpdateParam updateParam) {
        SysPerm sysPerm = new SysPerm();
        BeanUtils.copyProperties(updateParam, sysPerm);
        sysPermMapper.updateById(sysPerm);
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
    @Override
    public void deleteById(String id) {
        // 1、如果存在子权限，提示不能删除（select count(1) from sys_perm where parent_id = #{id}）
        LambdaQueryWrapper<SysPerm> countWrapper = new LambdaQueryWrapper<>();
        countWrapper.eq(SysPerm::getParentId,id);
        Long count = sysPermMapper.selectCount(countWrapper);
        if(count != null && count > 0){
            throw new BusinessException(500,"存在子权限，不能直接删除！请先删除子权限！");
        }
        // 2、删除角色权限关联关系
        LambdaQueryWrapper<SysRolePerm> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRolePerm::getPermId,id);
        sysRolePermService.remove(wrapper);
        // 3、删除权限
        sysPermMapper.deleteById(id);
    }
}
